/*******************************************************************************
filename      Parser.h
author        Craig Williams
last modified 03-10-2010
version       8.9

Description:
  Provides a parser library, as well as several string manipulation funcitons
    to allow for easy parseing of a file. The library handles all file input
    and as much clean up as possiable.

  WARNING: This library heavly uses malloc. The character array returned by
           GrabToken(), PeekToken(), and GrabBytes(<bytes>) must be freeded with
           free(<char *>); manually.

           There are no memory leaks inside the parser library.

  NOTE: Unicode is not supported.

  NOTE: Only Little Endian is supported. This only effects GrabBinary*()

  Parser Functions:
      ParserInit      - Initializer. Takes in a string that contains
                          the file to load, as well as how many bytes to read
                          in from the file at one time (Recommended: 1 KB)
      ParserDeInit    - Frees all the memory used by the parser
      LoadFile        - Opens and loads a new text file into the parser.
      LoadMemory      - Loads a chunk of memory (char *) into the parser for
                          processing. In other words, don't use internal file
                          handleing.
      LoadMemoryLen   - Same as above; however, it takes in the lenght of the
                          memory.
      ParserEnable    - Enables the specifed Parser feature
      ParserIsEnabled - Returns !0 if the specified feature(s) are enabled
      ParserDisable   - Disables the specified Parser feature
      AddTokenSet     - Adds another Token set. Allows for easy switching
                          between various parseing modes, as well as a built in
                          branching system.
      SetTokenSet     - Changes the current Token Set.
      GetTokenSet     - Returns the current Token Set.
      AddTokenSeparator - Adds a new "Token Separator" to the current token set.
                            A Token Separator is simply the string to check for
                            in the string we are parseing. Depending on the
                            flags you pass in, you can remove this token
                            from being returned from Grab/Peek Token, or do
                            some basic branching.
      AddTokenSep     - Calls the above function, with the default values.
      GrabToken       - Gets the next token from the string, and then updates
                          our position in the string.
      PeekToken       - Gets the next token from the string without updateing
                          our position in the string. All token logic, except
                          for callbacks, is taken into account.
      GrabInt         - Gets the next token from the string, and attempts to
                          convert it to a int. This function handles all
                          required cleanup.
      GrabFloat       - Gets the next token from the string, and attempts to
                          convert it to a float. This function handles all
                          required cleanup.
      GrabBinaryInt   - Reads in the next sizeof(int) bytes, and returns them
      GrabBinaryFloat - Reads in the next sizeof(float) bytes, and returns them
      GrabByte        - Reads in the next byte, and returns it.
      PeekByte        - Same as GrabByte(); however, the Parser state is not
                          modified.
      GrabBytes       - Reads in a specific number of bytes from the file, and
                          returns them.
      Seek            - Searches the string for the specified token, and then
                          updates our position in the string, to the character
                          directly following the token.
      SetFilePosition - Changes our location in the file, and reads in the new
                          data, from the specifed location.
      GetFilePosition - Returns the current file position.
      GetFileSize     - Returns the size of the loaded file/block of memory
      End             - Returns 1 if there was a error, or if we reached the end
                          of the file - No more processing possiable.
      GetParams       - Returns the last paramater associated with the last
                          found token separator.
      PushParserState - Pushes the current Parser state onto the Parser's State
                          statck, and sets a new/un-initilized Parser state as
                          the active state.
      PopParserState  - DeInits the current Parser State, and restores a older
                          state. If no old states exist, a new/un-initilized
                          state will be created and set as the active state.
      GetParserState  - Returns a pointer to the current Parser state.
      SetParserState  - Changes the current Parser state to the specifed state
      ErrorCode       - Returns the current error code (check defines in
                          parser_core.h).
      PrintErrorCode  - Prints out the Error Code, in a text format to the
                          command prompt.
      ParserMemoryUsage-Returns a estimate of how much memory the Parser is
                          currently using. This number is in bytes. Typically,
                          this value will be 100% correct; however, it can
                          deviate if a RegEx fails to compile.
      GenericDiscard  - Supplied Parser callback, that discards the next token

  String Manipulaiton functions:
      RemoveWhiteSpaces - Removes all white spaces from a string (Space, New
                            Line, Carriage Return, and Tab)
      ToUpper     - Converts all letters in a string to upper case
      ToLower     - Converts all letters in a string to lower case
      Dup         - Creates a copy of the specfied string
      DupLen      - Same as above, but it takes in the length of the string
      DupRange    - Creates a copy of a specific part of a string
      DupRangeFile- Creates a copy of a specific part of a file
      Cmp         - Compairs two strings. If they are equal, 1 is returned. If
                      not, 0 is returned.
*******************************************************************************/
#ifndef PARSER_CORE
#define PARSER_CORE

  /* Parser error codes. PrintError() will automatically translate these error*
   *   codes to the command prompt.                                           */
#define PARSER_NOT_INITIALIZED       -1
#define PARSER_NO_ERROR               0
#define PARSER_COULD_NOT_OPEN_FILE    1
#define PARSER_OUT_OF_MEMORY          2
#define PARSER_END_OF_FILE            3
#define PARSER_MEMORY_NOT_VALID       4
#define PARSER_GRAB_TOKEN_IGNORE      5

  /* AddTokenSeparator() switch to helper defines                             */
#define PARSER_TSET_DONT_SWITCH      -1
#define PARSER_TSET_LAST             -2

  /* Error codes returned from AddTokenSeparator()                            */
/* PARSER_NO_ERROR */
#define PARSER_TOKEN_NULL            (1 <<  0)
/*      PARSER_OUT_OF_MEMORY         (1 <<  1) --- Same as define above       */
#define PARSER_REGEX_COMPILE_ERROR   (1 <<  2)
#define PARSER_UNBALANCED_PARENS     (1 <<  3) /* Unbalanced () in RegEx      */
#define PARSER_UNBALANCED_BRACKETS   (1 <<  4) /* Unbalanced [] in RegEx      */

  /* Parser Config Defines for ParserEnable() and ParserDisable()             */
#define PARSER_HASH                  (1 <<  0)
#define PARSER_CASE_INSENSITIVE      (1 <<  1)
#define PARSER_WILDCARD              (1 <<  2)
#define PARSER_GLOBBING              PARSER_WILDCARD
#define PARSER_REGULAR_EXPRESSIONS   (1 <<  3)
#define PARSER_REGEX                 PARSER_REGULAR_EXPRESSIONS
#define PARSER_CLOSE_FILE            (1 <<  4)
#define PARSER_SORT_TOKEN_SEPS       (1 <<  5)

  /* When enabled, the parser will not attempt to free or duplicate the ptr   *
   *   that is passed to it. This is useful when you are only passing hard    *
   *   coded pointers to the parser.                                          */
#define PARSER_CONST_FILE_NAME       (1 <<  6)
#define PARSER_CONST_LOAD_MEMORY     (1 <<  7)
#define PARSER_CONST_TOKEN_SEPS      (1 <<  8)

  /* When enabled, the parser will not attempt to duplicate the pointer passed*
   *   to it; however, it will free the pointers when its done. This is useful*
   *   when you are passing dynamicly allocated memory to the parser, and dont*
   *   want to free() the memory manually.                                    */
#define PARSER_OWNS_FILE_NAME        (1 <<  9)
#define PARSER_OWNS_LOAD_MEMORY      (1 << 10)
#define PARSER_OWNS_TOKEN_SEPS       (1 << 11)

#define PARSER_ALL_OPTIONS           0xFFF


typedef char *(*PARSER_CALLBACK)(char *, void *);
typedef PARSER_CALLBACK PCBACK;

  /* Parser Functions */
void  ParserInit       (const char *file,
                        int   bufsize      );
void  ParserDeInit     (void               );
int   LoadFile         (const char *file   );
int   LoadMemory       (const char *memory );
int   LoadMemoryLen    (const char *mem,
                        int   len          );
void  ParserEnable     (int   flags        );
int   ParserIsEnabled  (int   flags        );
void  ParserDisable    (int   flags        );
int   AddTokenSet      (void               );
int   SetTokenSet      (int   tokenset     );
int   GetTokenSet      (void               );
int   AddTokenSeparator(const char *token,
                        int   Return,         /* default -  1 Return as token */
                        int   switchto,       /* default - -1 Dont change Tset*/
                        int   ignore,         /* default -  0 Dont ignore     */
                        char*(*fun)(char *, void*), /*default -  0 No CBack   */
                        void *params       ); /* default -  0 No callback parm*/
int   AddTokenSep      (const char *sp     ); /* AddTokenSeparator with defaul*/
char *GrabToken        (void               );
char *PeekToken        (void               );
int   GrabInt          (void               );
float GrabFloat        (void               );
int   GrabBinaryInt    (void               );
float GrabBinaryFloat  (void               );
unsigned char GrabByte (void               );
unsigned char PeekByte (int  offset        );
unsigned char*GrabBytes(int   bytes        );
int   Seek             (const char *search );
int   SetFilePosition  (long  fpos         );
long  GetFilePosition  (void               );
long  GetFileSize      (void               );
int   End              (void               );
void *GetParams        (void               );
int   PushParserState  (void               );
void  PopParserState   (void               );
void *GetParserState   (void               );
void  SetParserState   (void *state        );
int   ErrorCode        (void               );
void  PrintErrorCode   (void               );
int   ParserMemoryUsage(void               );

  /* Generic Parser Callbacks */
char *GenericDiscard   (char *, void *     );

  /* String Minipulation Functions */
int   RemoveWhiteSpaces(char *sp                            );
char *ToUpper          (char *sp                            );
char *ToLower          (char *sp                            );
char *Dup              (const char *sp                      );
char *DupLen           (const char *sp,   int len           );
char *DupRange         (const char *sp,   int start, int end);
char *DupRangeFile     (const char *file, int start, int end);
char  Cmp              (const char *osp,  const char *osp2  );

#endif
